import abc
import matplotlib.pyplot as plt
import seaborn as sbn
import os
import pathlib
import jieba
import wordcloud
from PIL import Image
import imageio
import numpy as np
from sklearn.decomposition import PCA
from librosa import display, load
import cv2


class Plotter(metaclass=abc.ABCMeta):
	@abc.abstractmethod
	def plot(self, *args, **kwargs):
		pass


class PointPlotter(Plotter):
	def __init__(self, point_data):
		self._data = point_data

	def plot(self):
		plt.figure(figsize=(5, 5))
		for x, y in self._data:
			plt.scatter(x, y)
		plt.savefig("PointPlot.png")


class ArrayPlotter(Plotter):
	def __init__(self, array_data):
		self._data = array_data

	def plot(self):
		plt.figure(figsize=(5, 5))
		if len(self._data) == 2:
			sbn.scatterplot(self._data[0], self._data[1])
		elif len(self._data) == 3:
			plt.subplot(111, projection='3d')
			sbn.scatterplot(self._data[0], self._data[1], self._data[2])
		plt.savefig("ArrayPlot.png")


class TextPlotter(Plotter):
	def __init__(self, text_data):
		jieba.add_word("纳西妲")
		jieba.add_word("草原核")
		jieba.add_word("灭净三业")
		jieba.add_word("蕴种印")
		# 作为文本中的固有名词，加入分词词典防止被错误划分
		self._text = jieba.lcut(text_data)

	def plot(self):
		word_str = ' '.join(self._text)
		wc = wordcloud.WordCloud(
			font_path="c/windows/fonts/simkai.ttf",
			background_color='white',
			width=1920,
			height=1080,
		)
		wc.generate(word_str)
		wc.to_file("WordCloudPlot.png")


class ImagePlotter(Plotter):
	def __init__(self, image_data):
		self._data = image_data

	def plot(self, row=2, column=3):
		plt.figure(figsize=(10, 10))
		for i in range(1, len(self._data) + 1):
			image = Image.open(self._data[i - 1])
			plt.subplot(row, column, i)
			plt.imshow(image)
		plt.savefig("ImagePlot.png")


class GifPlotter(Plotter):
	def __init__(self, image_data):
		self._data = image_data

	def plot(self):
		gif_data = list()
		for item in self._data:
			gif_data.append(imageio.v3.imread(item))
		imageio.mimsave('GifPlot.gif', gif_data, fps=1)


class KeyFeaturePlotter(Plotter):
	def __init__(self, array_data):
		self._data = np.array(array_data)

	def pca_process(self):
		pca_model = PCA(n_components=2)
		self._data = pca_model.fit_transform(self._data)

	def plot(self):
		plt.figure(figsize=(10, 10))
		self.pca_process()
		sbn.scatterplot(self._data[0], self._data[1])
		plt.savefig("KeyFeaturePlot.png")


class MusickPlotter(Plotter):
	def __init__(self, music_data):
		self._data = music_data

	def plot(self):
		y, sr = load(self._data, sr=22500)
		plt.figure(figsize=(15, 10))
		display.waveshow(y, sr)
		plt.savefig("MusicPlot.png")


class VideoPlotter(Plotter):
	def __init__(self, video_data):
		self._data = video_data

	def plot(self):
		video_cap = cv2.VideoCapture(self._data)
		frame_count = 0
		frames = list()
		while True:
			ret, frame = video_cap.read()
			if not ret:
				break
			frame = frame[..., ::-1]
			if frame_count % 15 == 0:
				frames.append(frame)
				cv2.imshow('frame', frame)
				cv2.waitKey(1)
			frame_count += 1
		video_cap.release()
		cv2.destroyAllWindows()
		print("===>", len(frames))
		imageio.mimsave('video2gif.gif', frames, format='GIF')


class PlottingAdapter(Plotter):
	def __init__(self, plot_name):
		self._name = plot_name

	def plot(self):
		self._name.plot()


def main():
	point_data = [
		(1, 2), (2, 3), (3, 4), (4, 5),
		(5, 6), (6, 7), (7, 8), (8, 9)
	]
	point_inst = PointPlotter(point_data)
	# point_inst.plot()

	array_data = [
		[1, 2, 3, 4, 5, 6],
		[6, 5, 4, 3, 2, 1],
		[1, 2, 2, 2, 2, 3]
	]
	array_inst = ArrayPlotter(array_data)
	# array_inst.plot()

	text = open(
		r'D:\buaa_czw\2022 Autumn\General Programming 2022\Week 10\test contents\text_data.txt',
		'r',
		encoding='utf-8'
	).readlines()
	text_alter = list()
	for line in text:
		line = line.replace('\n', '')
		text_alter.append(line)
	textdata = ''.join(text_alter)
	text_inst = TextPlotter(textdata)
	# text_inst.plot()

	image_path = pathlib.Path(r'D:\buaa_czw\2022 Autumn\General Programming 2022\Week 10\test contents\gif image data')
	image_list = list(image_path.rglob('*.*'))

	image_inst = ImagePlotter(image_list)
	# image_inst.plot()

	gif_inst = GifPlotter(image_list)
	# gif_inst.plot()

	high_array_data = [
		[1, 2, 3, 4, 5, 6],
		[2, 3, 4, 5, 6, 7],
		[3, 4, 5, 6, 7, 8],
		[4, 5, 6, 7, 8, 9]
	]
	kf_inst = KeyFeaturePlotter(high_array_data)
	# kf_inst.plot()

	music_data = r'D:\buaa_czw\2022 Autumn\General Programming 2022\Week 10\test contents\FFXIV_Level_Up.mp3'
	mus_inst = MusickPlotter(music_data)
	# mus_inst.plot()

	video_data = r'D:\buaa_czw\2022 Autumn\General Programming 2022\Week 10\test contents\黎の軌跡Ⅱ OPムービー_Trim.mp4'
	vid_inst = VideoPlotter(video_data)
	# vid_inst.plot()

	adapters = list()
	adapters.append(PlottingAdapter(point_inst))
	adapters.append(PlottingAdapter(array_inst))
	adapters.append(PlottingAdapter(text_inst))
	adapters.append(PlottingAdapter(image_inst))
	adapters.append(PlottingAdapter(gif_inst))
	adapters.append(PlottingAdapter(kf_inst))
	adapters.append(PlottingAdapter(mus_inst))
	adapters.append(PlottingAdapter(vid_inst))

	for item in adapters:
		item.plot()


if __name__ == '__main__':
	main()
